package com.ruoyi.framework.web.service;

import com.alibaba.fastjson.JSON;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiUserGetRequest;
import com.dingtalk.api.request.OapiUserGetuserinfoRequest;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiUserGetResponse;
import com.dingtalk.api.response.OapiUserGetuserinfoResponse;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.framework.config.DingDingConfig;
import com.taobao.api.ApiException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

import static com.ruoyi.framework.config.UrlConstant.URL_GET_TOKEN;
import static com.ruoyi.framework.config.UrlConstant.URL_GET_USER_INFO;
import static com.ruoyi.framework.config.UrlConstant.URL_USER_GET;


/**
 * @Description
 * @Author Vzn
 * @Date 2021/4/18 13:23
 */
@Component
public class DingDingLoginService {

    private static final Logger log = LoggerFactory.getLogger(DingDingLoginService.class);

    @Autowired
    private TokenService tokenService;

    @Autowired
    private DingDingConfig dingDingConfig;

    @Autowired
    private RedisCache redisCache;


    public LoginUser dingDingLogin(String authCode){

        String accessToken = getAccessToken();
        OapiUserGetResponse response;
        try {
            DingTalkClient client = new DefaultDingTalkClient(URL_GET_USER_INFO);
            OapiUserGetuserinfoRequest req = new OapiUserGetuserinfoRequest();
            req.setCode(authCode);
            OapiUserGetuserinfoResponse rsp = client.execute(req, accessToken);
            System.out.println(rsp.getBody());
            if(!(rsp.getErrcode()==Long.valueOf(0)) || !rsp.isSuccess()){
                throw new CustomException("获取用户失败");
            }
            System.out.println(">>>>rsp="+JSON.toJSON(rsp));
            String userId = rsp.getUserid();

            client = new DefaultDingTalkClient(URL_USER_GET);
            OapiUserGetRequest request = new OapiUserGetRequest();
            request.setUserid(userId);
            request.setHttpMethod("GET");

            response = client.execute(request, accessToken);
            System.out.println(">>>>response="+JSON.toJSON(response));

        } catch (ApiException e) {
            throw new CustomException(e.getMessage());
        }


        LoginUser loginUser =new LoginUser();
        SysUser user =new SysUser();
        user.setNickName(response.getNickname());
        user.setUserName(response.getName());
        user.setEmail(response.getEmail());
        user.setDdUserId(response.getDingId());
        user.setPhonenumber(response.getMobile());
        loginUser.setUser(user);

        return loginUser;
    }

    private String getAccessToken() {
        log.error(">>>>getAccessToken");
        String accessToken = null;
        try {
            log.error(">>>>dingDingConfig.getAppKey()="+dingDingConfig.getAppKey());
            String accessTokenKey = Constants.ACCESS_TOKEN_KEY + dingDingConfig.getAppKey();
            log.error(">>>>accessTokenKey="+accessTokenKey);
            accessToken = redisCache.getCacheObject(accessTokenKey);
            log.error(">>>>accessToken="+accessToken);
            if (accessToken == null) {
                //新获取 AccessToken
                log.error(">>>>URL_GET_TOKEN="+URL_GET_TOKEN);
                DingTalkClient client = new DefaultDingTalkClient(URL_GET_TOKEN);
                OapiGettokenRequest req = new OapiGettokenRequest();
                req.setAppkey(dingDingConfig.getAppKey());
                req.setAppsecret(dingDingConfig.getAppSecret());
                req.setHttpMethod("GET");
                OapiGettokenResponse rsp = client.execute(req);
                accessToken = rsp.getAccessToken();
                //保存到 redis
                saveAccessToken(accessToken);
            }
            return accessToken;
        } catch (ApiException e) {
            log.error(">>>>ApiException=",e);
            throw new RuntimeException(e);
        }

    }
    private void saveAccessToken(String accessToken){
        String accessTokenKey =getAccessToken(dingDingConfig.getAppKey());
        redisCache.setCacheObject(accessTokenKey, accessToken, dingDingConfig.getExpireTime(), TimeUnit.MINUTES);
    }

    private String getAccessToken(String appKey)
    {
        return Constants.ACCESS_TOKEN_KEY + appKey;
    }


}
